<?php

namespace app\common\model;

use app\admin\model\consult\Order;
use app\admin\model\xlzxinfo\Xlzxinfo;
use GuzzleHttp\Client;
use think\Cache;
use think\cache\driver\Redis;
use think\Config;
use think\Env;
use think\Exception;
use think\Log;
use think\Model;
use think\Queue;
use think\Db;


/**
 * 云信留客
 */
class YunXin extends Model
{
    private static $url = "https://101.37.133.245:11008";
    private static $token = '1f05353d2f614ab4a9b580c103ab088d';
    private static $accountId = '107047';
    private static $version = '1.0.0';


    /*
     * 语音通知
     * */
    public static function notify($calleeNumber,$nickname='技师')
    {
        $params['calleeNumber'] = $calleeNumber;
        $params['templateID'] = '401649';
        $templateArgs = ['var1'=>$nickname];
        $params['templateArgs'] = $templateArgs;
        $res = self::send('notify',$params);
    }

    /*
     * AXB 模式绑定
     * */
    public static function AXB($bindNumberA,$bindNumberB)
    {
        $params['middleNumber'] = Env::get('yunxin.middleNumber', '');
        $params['bindNumberA'] = $bindNumberA;
        $params['bindNumberB'] = $bindNumberB;
        $params['maxBindingTime'] = 60;
        $res = self::send('middleNumberAXB',$params);
        $res = json_decode($res,true);
        if ($res['result']!='000000'){
            if ($res['result']=='400100'){
                $res['middleNumber'] = '01086460268';
//                Log::info($res);
                return $res;
            }
            throw new Exception("获取虚拟号码失败");
        }else{
            return $res;
        }
    }

    /*
     * 双向呼叫
     * */
    public static function twoWayCall($callerNumber,$calleeNumber,$maxDuration)
    {
//        $maxDuration = 3;
        $params['callerNumber'] = $callerNumber;
        $params['calleeNumber'] = $calleeNumber;
        $params['maxDuration'] = intval($maxDuration);
        $params['callbackUrl'] = 'https://xyxl.ranxuxing.com/addons/mental/consult/twoWayCallback';
        $arr = [
            'name'=>'语音咨询回调消息',
            'content'=>json_encode($params),
            'create_time'=>time(),
        ];
        Db::name('message_log')->insert($arr);
        Log::info('云呼参数');
        Log::info($params);
        $res = self::send('twoWayCall',$params);
        $res = json_decode($res,true);
        return $res;

    }

    /*
     * 双向呼叫-回调
     * */
    public static function twoWayCallback($param)
    {
        // $param = array (
        //    'accountId' => '107047',
        //    'asrTextUrl' => 'http://winnerlook-voice.oss-cn-hangzhou.aliyuncs.com/recording_file/KH_2021_107047/231103/231103f0527d4d76b5da63d718f3a283.html?Expires=1704184468&amp;OSSAccessKeyId=LTAIXDre9KQI2QOm&amp;Signature=6oij17v47ESCc3FhwIEr96oxVh0%3D',
        //    'callId' => '24100807a279412883d04c5aab0b5146',
        //    'calleeAnsweredTime' => '2023-11-03 16:34:10',
        //    'calleeDuration' => '15',
        //    'calleeNumber' => '15090540569',
        //    'calleeState' => '0',
        //    'callerAnsweredTime' => '2023-11-03 16:34:05',
        //    'callerDuration' => '20',
        //    'callerNumber' => '18610464953',
        //    'callerState' => '0',
        //    'displayNumber' => '02160781261',
        //    'duration' => '15',
        //    'endTime' => '2023-11-03 16:34:25',
        //    'is_del' => '0',
        //    'recUrl' => 'http://winnerlook-voice.oss-cn-hangzhou.aliyuncs.com/recording_file/KH_2021_107047/231103/231103f0527d4d76b5da63d718f3a283.wav?Expires=1704184468&amp;OSSAccessKeyId=LTAIXDre9KQI2QOm&amp;Signature=8pRisl1K1RhLQkBZQVtJL1N%2B4CA%3D',
        //    'runState' => '200',
        //    'startCallTime' => '2023-11-03 16:34:05',
        //    'addon' => 'mental',
        //    'controller' => 'consult',
        //    'action' => 'twoWayCallback',
        // );
        $arr = [
            'name'=>'双向呼叫回调成功消息',
            'content'=>json_encode($param),
            'create_time'=>time(),
        ];
        Db::name('message_log')->insert($arr);
        try {
            $YunxinCalllogModel =new YunxinCalllog();
            $log = $YunxinCalllogModel->where(['callId'=>$param['callId']])->find();
            if (!$log){
                return false;
            }

            //成功接通-更新开始服务
            $order = Order::where(['pay_status'=>'paid','id'=>$log['order_id']])->find();
            if (!$order){
                return false;
            }
            //先 更新拨打记录
            $log->startCallTime      = isset($param['startCallTime']) ? strtotime($param['startCallTime']) : '';
            $log->callerAnsweredTime = isset($param['callerAnsweredTime']) ? strtotime($param['callerAnsweredTime']) : '';
            $log->calleeAnsweredTime = isset($param['calleeAnsweredTime']) ? strtotime($param['calleeAnsweredTime']) : '';
            $log->endTime            = isset($param['endTime']) ? strtotime($param['endTime']) : '';
            $log->callerState        = $param['callerState'];
            $log->calleeState        = $param['calleeState'];
            $log->callerDuration     = $param['calleeDuration'];
            $log->duration           = $param['duration'];
            $log->updatetime         = time();
            $log->logs         = json_encode($param);
            $log->save();

            // 再统计拨打记录时间是不是和订单分钟一致
            //同步咨询订单主表的  时间
            if(!empty($order)){

                // 最近一次通话时间
                $order->talk_time = $param['calleeAnsweredTime']? strtotime($param['calleeAnsweredTime']):0;

                // 第一次通话时间
                if($order['start_talk_time']==0){
                    $order->start_talk_time = $param['calleeAnsweredTime']? strtotime($param['calleeAnsweredTime']):0;
                }else if(strtotime($param['calleeAnsweredTime'])<$order['start_talk_time']){
                    $order->start_talk_time = $param['calleeAnsweredTime']? strtotime($param['calleeAnsweredTime']):0;
                }

                // 最后一给通话结束时间
                if($order['end_talk_time']<strtotime($param['endTime'])){
                    $order->end_talk_time = $param['endTime']? strtotime($param['endTime']):0;
                }

                //统计打电话记录 总耗时 秒为单位
                $duration = $YunxinCalllogModel->where(['order_id'=>$order['id']])->sum('duration');

                // if($order['minutes'] == intval(bcdiv($duration,60))){
                //     $order->status = 3;//已完成
                // }else{
                //     $order->status = 2;//处理中
                // }
                $order->talk_duration = intval(bcdiv($duration,60));
                // $order->save(); 
            }


            if ($param['callerState']==0 && $param['calleeState']==0 && $param['calleeAnsweredTime']){
                //计算佣金
                // $commission_rate = Config::get('site.commission_rate');
                $commission_rate = Config::get('site.xlzx_commission_rate');
                $commission_price = bcMath($order['price'],$commission_rate/100,'*',2);
                //更新开始服务时间
                if(empty($order->server_start_time)){
                    $order->server_start_time = $param['calleeAnsweredTime'];
                }
                $order->status = 2;//服务中
                // 如果拨打记录 时间大于且等于订单分钟，才更新结束时间
                if(intval(bcdiv($duration,60))>= $order['minutes']){
                    $order->server_end_time = $param['endTime'];

                    $order->commission_price = $commission_price;
                    $order->commission_rate = $commission_rate;
                    $order->status = 3;//拨打时间一致，已完成

                    //后期调整兑换码订单这里不支持  咨询师   语音  佣金
                    if($order['pay_type'] != 'code'){
                        //给咨询师分佣
                        $xlzxinfo = Xlzxinfo::where(['id'=>$order['xlzxinfo_id']])->find();
                        User::money($commission_price,$xlzxinfo['user_id'],'语音咨询订单佣金'.$commission_rate.'% <br/>咨询订单号:'.$log['order_id'].'<br/>订单编号'.$order['order_sn'],7);
                        //累计收益
                        // \think\Db::name('user')->where('id', $xlzxinfo['user_id'])->setInc('cumulative_gain',$commission_rate);
                        //订单更改为已经完成分佣
                        Order::where(['pay_status'=>'paid','id'=>$log['order_id']])->update(['is_rebate'=>1]);
                    }

                    //存在用户的上级，推广订单佣金计算
                    $user = \think\Db::name('user')->where('id', $order['user_id'])->where('status', 'normal')->find();
                    if ($user) {
                        //上下级推广佣金
                        $parent_user = \think\Db::name('user')->where('id', $user['pid'])->where('status', 'normal')->find();
                        if ($parent_user){
                            //后期调整兑换码订单这里不支持分佣
                            if($order['pay_type'] != 'code'){
                                //分佣比例
                                if ($parent_user['commission_rate']>0){
                                    $commission_rate1 = $parent_user['commission_rate'];
                                }else{
                                    $commission_rate1 = Config::get('site.commission_rate');
                                }
                                $commission_rate_parent = bcMath($commission_rate1,100,'/');
                                $price2 = bcMath($order->price,$commission_rate_parent,'*');
                                $memo = '用户推广语音咨询分佣 比例'.$commission_rate1.'% <br/>订单编号:'.$log['order_id'];
                                //给到余额
                                \app\common\model\User::money($price2,$parent_user['id'],$memo,5);
                                \think\Db::name('user')->where('id', $parent_user['id'])->setInc('cumulative_gain',$price2);

                                //订单更改为已经完成分佣
                                Order::where(['pay_status'=>'paid','id'=>$log['order_id']])->update(['is_rebate'=>1]);

                            }
                        }
                    }
    //                $job = 'app\job\ConsultJob'; // 当前任务由哪个类负责处理
    //                $queueName = 'consult_job_queue';  // 当前队列归属的队列名称
    //                $second = $order['minutes'] * 60;
    //                $res = Queue::later($second,$job, $order['id'], $queueName);   // 订单到期
    //
    //                $second2 = $second - 300;//剩余5分钟提醒
    //                $res = Queue::later($second2,'app\job\XufeiJob', $order['id'], 'xufei_job_queue');   // 订单续费提醒
//                
                }
                // if(!empty($order['server_start_time'])){
                //     $minutes = $order['minutes']*60;
                //     $newTimestamp = date('Y-m-d H:i:s',strtotime($order->server_start_time)+$minutes);
                //     if(strtotime($param['endTime'])>strtotime($newTimestamp)){
                //         $order->status = 3;
                //     }
                // }else{
                //     $minutes = $order['minutes']*60;
                //     $newTimestamp = date('Y-m-d H:i:s',strtotime($param['calleeAnsweredTime'])+$minutes);
                //     if(strtotime($param['endTime'])>strtotime($newTimestamp)){
                //         $order->status = 3;
                //     }
                // }
            }
            $order->save();
        } catch (\Exception $e) {
            $arr = [
                'name'=>'双向呼叫回调失败消息',
                'content'=>json_encode($param),
                'create_time'=>time(),
            ];
            Db::name('message_log')->insert($arr);
            Log::info('呼叫回调error:');
            Log::info($e->getMessage());
            return false;
        }

        return true;
    }

//3呼叫状态
//呼叫状态码	呼叫状态	备注
//0	正常
//1	空号
//2	用户忙
//3	拒接
//4	无人接听
//5	无法接通
//6	呼叫被拦截	呼叫被运营商拦截
//7	关机
//8	停机
//9	其他	呼叫失败或无法识别的状态
//10	主叫挂机
//11	被叫挂机
//12	主叫放弃
//13	小号状态异常
//14	订单超期
//15	平台异常
    public static  function send($functionCode,$params){
        $platform = 'voice';
        $version = self::$version;
        $accountId = self::$accountId;
        $token = self::$token;
        $now = self::getMillisecond();
        $sig = $accountId.$token.$now;
        $sig = md5($sig);
        $Authorization = self::$accountId.':'.$now;
        $Authorization = base64_encode($Authorization);
        $uri = "/".$platform."/".$version."/".$functionCode."/".$accountId."/".$sig;
        $client = new Client(['base_uri'=>self::$url]);
        $response = $client->request('POST',$uri,[
            'json'=>$params,
            'headers'=>[
                'Authorization'=>$Authorization,
                'Content-Type'=>'application/json',
                'Accept'=>'application/json',
            ],
            'verify' => false
        ]);
        $response = $response->getBody()->getContents();
        Log::info('云呼响应');
        Log::info($response);
        return $response;
    }
    public static function getMillisecond() {
        list($s1, $s2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
    }

    // 模拟提交数据函数
    public static function httpPost($url,$header,$data){
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求
//        curl_setopt($curl, CURLOPT_POSTFIELDS,  $data); // Post提交的数据包
        curl_setopt($curl, CURLOPT_POSTFIELDS,  http_build_query($data)); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, $header); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
        $result = curl_exec($curl); // 执行操作
//        if (curl_errno($curl)) {
//            return 'Error POST'.curl_error($curl);
//        }
        curl_close($curl); // 关键CURL会话
        return $result; // 返回数据
    }


}
